home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch13 / Pline3d.cls < prev    next >
Text File  |  1999-06-20  |  6KB  |  228 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Polyline3d"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = False
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' Point3D and Segment3D are defined in module M3OPS.BAS as:
  17. '    Type Point3D
  18. '        coord(1 To 4) As Single
  19. '        trans(1 To 4) As Single
  20. '    End Type
  21. '
  22. '    Type Segment3D
  23. '        pt1 As Integer
  24. '        pt2 As Integer
  25. '    End Type
  26.  
  27. Private NumPoints As Integer ' Number of points.
  28. Private Points() As Point3D  ' Data points.
  29.  
  30. Private NumSegs As Integer   ' Number of segments.
  31. Private Segs() As Segment3D  ' The segments.
  32.  
  33. ' Create a pyramid with height L and base given
  34. ' by the points in the coord array. Add the
  35. ' segments that make up the pyramid to this
  36. ' polyline.
  37. Public Sub Stellate(L As Single, ParamArray coord() As Variant)
  38. Dim x0 As Single
  39. Dim y0 As Single
  40. Dim z0 As Single
  41. Dim x1 As Single
  42. Dim y1 As Single
  43. Dim z1 As Single
  44. Dim x2 As Single
  45. Dim y2 As Single
  46. Dim z2 As Single
  47. Dim x3 As Single
  48. Dim y3 As Single
  49. Dim z3 As Single
  50. Dim Ax As Single
  51. Dim Ay As Single
  52. Dim Az As Single
  53. Dim Bx As Single
  54. Dim By As Single
  55. Dim Bz As Single
  56. Dim Nx As Single
  57. Dim Ny As Single
  58. Dim Nz As Single
  59. Dim num As Integer
  60. Dim i As Integer
  61. Dim pt As Integer
  62.  
  63.     num = (UBound(coord) + 1) \ 3
  64.     If num < 3 Then
  65.         Beep
  66.         MsgBox "Must have at least 3 points to stellate.", , vbExclamation
  67.         Exit Sub
  68.     End If
  69.     
  70.     ' (x0, y0, z0) is the center of the polygon.
  71.     x0 = 0
  72.     y0 = 0
  73.     z0 = 0
  74.     pt = 0
  75.     For i = 1 To num
  76.         x0 = x0 + coord(pt)
  77.         y0 = y0 + coord(pt + 1)
  78.         z0 = z0 + coord(pt + 2)
  79.         pt = pt + 3
  80.     Next i
  81.     x0 = x0 / num
  82.     y0 = y0 / num
  83.     z0 = z0 / num
  84.     
  85.     ' Find the normal.
  86.     x1 = coord(0)
  87.     y1 = coord(1)
  88.     z1 = coord(2)
  89.     x2 = coord(3)
  90.     y2 = coord(4)
  91.     z2 = coord(5)
  92.     x3 = coord(6)
  93.     y3 = coord(7)
  94.     z3 = coord(8)
  95.     Ax = x2 - x1
  96.     Ay = y2 - y1
  97.     Az = z2 - z1
  98.     Bx = x3 - x2
  99.     By = y3 - y2
  100.     Bz = z3 - z2
  101.     m3Cross Nx, Ny, Nz, Ax, Ay, Az, Bx, By, Bz
  102.     
  103.     ' Give the normal length L.
  104.     m3SizeVector L, Nx, Ny, Nz
  105.     
  106.     ' The normal + <x0, y0, z0> gives the point.
  107.     x0 = x0 + Nx
  108.     y0 = y0 + Ny
  109.     z0 = z0 + Nz
  110.  
  111.     ' Build the segments that make up the object.
  112.     x1 = coord(3 * num - 3)
  113.     y1 = coord(3 * num - 2)
  114.     z1 = coord(3 * num - 1)
  115.     pt = 0
  116.     For i = 1 To num
  117.         x2 = coord(pt)
  118.         y2 = coord(pt + 1)
  119.         z2 = coord(pt + 2)
  120.         AddSegment x1, y1, z1, x2, y2, z2, x0, y0, z0
  121.         x1 = x2
  122.         y1 = y2
  123.         z1 = z2
  124.         pt = pt + 3
  125.     Next i
  126. End Sub
  127.  
  128. ' Add one or more line segments to the polyline.
  129. Public Sub AddSegment(ParamArray coord() As Variant)
  130. Dim num_segs As Integer
  131. Dim i As Integer
  132. Dim last As Integer
  133. Dim pt As Integer
  134.  
  135.     num_segs = (UBound(coord) + 1) \ 3 - 1
  136.     ReDim Preserve Segs(1 To NumSegs + num_segs)
  137.  
  138.     last = AddPoint((coord(0)), (coord(1)), (coord(2)))
  139.     pt = 0
  140.     For i = 1 To num_segs
  141.         Segs(NumSegs + i).pt1 = last
  142.         pt = pt + 3
  143.         last = AddPoint((coord(pt)), (coord(pt + 1)), (coord(pt + 2)))
  144.         Segs(NumSegs + i).pt2 = last
  145.     Next i
  146.  
  147.     NumSegs = NumSegs + num_segs
  148. End Sub
  149. ' Add a point to the polyline or reuse a point.
  150. ' Return the point's index.
  151. Private Function AddPoint(ByVal X As Single, ByVal Y As Single, ByVal Z As Single) As Integer
  152. Dim i As Integer
  153.  
  154.     ' See if the point is already here.
  155.     For i = 1 To NumPoints
  156.         If X = Points(i).coord(1) And _
  157.            Y = Points(i).coord(2) And _
  158.            Z = Points(i).coord(3) Then _
  159.                 Exit For
  160.     Next i
  161.     AddPoint = i
  162.     
  163.     ' If so, we're done.
  164.     If i <= NumPoints Then Exit Function
  165.     
  166.     ' Otherwise create the new point.
  167.     NumPoints = NumPoints + 1
  168.     ReDim Preserve Points(1 To NumPoints)
  169.     Points(i).coord(1) = X
  170.     Points(i).coord(2) = Y
  171.     Points(i).coord(3) = Z
  172.     Points(i).coord(4) = 1#
  173. End Function
  174.  
  175.  
  176. ' Apply a transformation matrix which may not
  177. ' contain 0, 0, 0, 1 in the last column to the
  178. ' object.
  179. Public Sub ApplyFull(M() As Single)
  180. Dim i As Integer
  181.  
  182.     For i = 1 To NumPoints
  183.         m3ApplyFull Points(i).coord, M, Points(i).trans
  184.     Next i
  185. End Sub
  186.  
  187. ' Apply a transformation matrix to the object.
  188. Public Sub Apply(M() As Single)
  189. Dim i As Integer
  190.  
  191.     For i = 1 To NumPoints
  192.         m3Apply Points(i).coord, M, Points(i).trans
  193.     Next i
  194. End Sub
  195.  
  196.  
  197. ' Apply a nonlinear transformation.
  198. Public Sub Transform(ByVal T As Distortion)
  199. Dim i As Integer
  200.  
  201.     For i = 1 To NumPoints
  202.         T.Transform Points(i).coord(1), Points(i).coord(2), Points(i).coord(3)
  203.     Next i
  204. End Sub
  205.  
  206. ' Draw the transformed points on a PictureBox.
  207. Public Sub Draw(ByVal pic As PictureBox, Optional R As Variant)
  208. Dim seg As Integer
  209. Dim pt1 As Integer
  210. Dim pt2 As Integer
  211. Dim dist As Single
  212.  
  213.     On Error Resume Next
  214.     If IsMissing(R) Then R = INFINITY
  215.     dist = R
  216.     For seg = 1 To NumSegs
  217.         pt1 = Segs(seg).pt1
  218.         pt2 = Segs(seg).pt2
  219.         ' Don't draw if either point is farther
  220.         ' from the focus point than the center of
  221.         ' projection (which is distance dist away).
  222.         If (Points(pt1).trans(3) < R) And (Points(pt2).trans(3) < R) Then _
  223.             pic.Line _
  224.                 (Points(pt1).trans(1), Points(pt1).trans(2))- _
  225.                 (Points(pt2).trans(1), Points(pt2).trans(2))
  226.     Next seg
  227. End Sub
  228.